package at.ac.tuwien.infosys.aic11.testclient;

import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;


import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.io.CachedOutputStream;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor;
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
import org.apache.ws.security.handler.WSHandlerConstants;

import at.ac.tuwien.infosys.aic11.dto.Address;
import at.ac.tuwien.infosys.aic11.dto.BankTransfer;
import at.ac.tuwien.infosys.aic11.dto.Cheque;
import at.ac.tuwien.infosys.aic11.dto.CreditRequest;
import at.ac.tuwien.infosys.aic11.dto.DisbursementPreference;
import at.ac.tuwien.infosys.aic11.dto.Duration;
import at.ac.tuwien.infosys.aic11.dto.InterestRate;
import at.ac.tuwien.infosys.aic11.dto.InternalCustomer;
import at.ac.tuwien.infosys.aic11.dto.Money;
import at.ac.tuwien.infosys.aic11.dto.Offer;
import at.ac.tuwien.infosys.aic11.dto.Rating;
import at.ac.tuwien.infosys.aic11.dto.Warrantor;
import at.ac.tuwien.infosys.aic11.fault.UnknownAddressFault;
import at.ac.tuwien.infosys.aic11.fault.UnknownCustomerFault;
import at.ac.tuwien.infosys.aic11.fault.UnknownDisbursementPreferenceFault;
import at.ac.tuwien.infosys.aic11.fault.UnknownDurationFault;
import at.ac.tuwien.infosys.aic11.fault.UnknownMoneyFault;
import at.ac.tuwien.infosys.aic11.fault.UnknownOfferFault;
import at.ac.tuwien.infosys.aic11.fault.UnknownRatingFault;
import at.ac.tuwien.infosys.aic11.fault.UnknownRequestFault;
import at.ac.tuwien.infosys.aic11.services.ContractManagement;
import at.ac.tuwien.infosys.aic11.services.ShippingService;


public final class Client {
	
	private static Logger log = Logger.getLogger("Testclient");

	private static ArrayList<CreditRequest> requests = new ArrayList<CreditRequest>();

	private Client() {
	}

	public static void main(String args[]) throws Exception {
		/*
		 * log.info("Sent HTTP GET request to query customer info");
		 * URL url = new
		 * URL("http://localhost:9000/ratingservice/ratings/sackbauer");
		 * InputStream in = url.openStream();
		 * log.info(getStringFromInputStream(in));
		 */

		testWS();
		log.info("\n");
	}

	@SuppressWarnings("unused")
	private static String getStringFromInputStream(InputStream in)
			throws Exception {
		CachedOutputStream bos = new CachedOutputStream();
		IOUtils.copy(in, bos);
		in.close();
		bos.close();
		return bos.getOut().toString();
	}

	private static void testWS() {

		createCreditRequestForTest();
		CreditRequest cr = requests.get(3);

		/****************************
		 * contract management service*
		 ****************************/
		// das sollte eigentlich der contract management service sein. TODO:
		// umbenennen
		JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
		factory.getInInterceptors().add(new LoggingInInterceptor());
		factory.getOutInterceptors().add(new LoggingOutInterceptor());

		Map<String, Object> inProps = new HashMap<String, Object>();
		inProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.TIMESTAMP
				+ " " + WSHandlerConstants.SIGNATURE + " "
				+ WSHandlerConstants.ENCRYPT);
		inProps.put(WSHandlerConstants.SIG_PROP_FILE,
				"META-INF/clerk_cert.properties");
		inProps.put(WSHandlerConstants.DEC_PROP_FILE,
				"META-INF/clerk_cert.properties");
		inProps.put(WSHandlerConstants.PW_CALLBACK_CLASS,
				at.ac.tuwien.infosys.aic11.testclient.PasswordHandler.class.getName());

		WSS4JInInterceptor wssIn = new WSS4JInInterceptor(inProps);
		factory.getInInterceptors().add(wssIn);

		Map<String, Object> outProps = new HashMap<String, Object>();
		outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.TIMESTAMP
				+ " " + WSHandlerConstants.SIGNATURE + " "
				+ WSHandlerConstants.ENCRYPT);
		outProps.put(WSHandlerConstants.USER, "clerk");
		outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS,
				at.ac.tuwien.infosys.aic11.testclient.PasswordHandler.class.getName());
		outProps.put(WSHandlerConstants.ENCRYPTION_USER, "crmserver");
//		outProps.put(WSHandlerConstants.ENC_SYM_ALGO, "http://www.w3.org/2001/04/xmlenc#tripledes-cbc");
//		outProps.put(WSHandlerConstants.ENC_KEY_TRANSPORT, "http://www.w3.org/2001/04/xmlenc#rsa-1_5");
		outProps.put(WSHandlerConstants.SIG_PROP_FILE,
				"META-INF/clerk_cert.properties");
		outProps.put(WSHandlerConstants.ENC_PROP_FILE,
				"META-INF/clerk_cert.properties");

		WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
		factory.getOutInterceptors().add(wssOut);

		log.info("wss4j setup done");

		factory.setServiceClass(ContractManagement.class);
		factory.setAddress("http://localhost:9001/ContractManagementService");
		ContractManagement client = (ContractManagement) factory.create();

		cr.getCustomer().setRating(new Rating("AAA"));
		
		Offer offer;
		try {
			offer = client.getOffer(cr);
			log.info("Got an offer: " + offer.getComments());
			cr.setOffer(offer);
		} catch (UnknownRequestFault e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (UnknownCustomerFault e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (UnknownMoneyFault e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (UnknownRatingFault e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (UnknownDurationFault e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		

		/*******************
		 * shipping service*
		 *******************/
		JaxWsProxyFactoryBean factory2 = new JaxWsProxyFactoryBean();
		factory2.getInInterceptors().add(new LoggingInInterceptor());
		factory2.getOutInterceptors().add(new LoggingOutInterceptor());
		factory2.setServiceClass(ShippingService.class);
		factory2.setAddress("http://localhost:9001/ShippingService");
		ShippingService client2 = (ShippingService) factory2.create();

		try {
			client2.finaliseContract(cr);
		} catch (UnknownRequestFault e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnknownCustomerFault e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnknownDisbursementPreferenceFault e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnknownMoneyFault e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnknownAddressFault e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnknownOfferFault e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	@SuppressWarnings("unused")
	private static void createCreditRequestForTest() {
		Address a1 = new Address("id_a1", "karlsplatz", "wien", "314", "1",
				"1040");
		Address a2 = new Address("id_a2", "stephansplatz", "wien", "123", "2",
				"1010");
		Address a3 = new Address("id_a3", "getreidemarkt ", "wien", "456", "3",
				"1060");
		Address a4 = new Address("id_a4", "museumsplatz", "wien", "789", "4",
				"1070");
		Address a5 = new Address("id_a5", "linke wienzeile", "wien", "12", "5",
				"1040");

		DisbursementPreference dp1 = new Cheque("max mustermann");
		DisbursementPreference dp2 = new Cheque("apfel saft");
		DisbursementPreference dp3 = new BankTransfer("sparkasse", "12345",
				"5678");
		DisbursementPreference dp4 = new BankTransfer("volksbank", "34589",
				"7890");
		DisbursementPreference dp5 = new BankTransfer("bank austria", "89012",
				"2345");

		Rating r1 = new Rating("AAA");
		Rating r2 = new Rating("AA");
		Rating r3 = new Rating("AAMinus");
		Rating r4 = new Rating("APlus");
		Rating r5 = new Rating("A");
		

		Money m1 = new Money(30000, "eur");
		Money m2 = new Money(10000, "eur");
		Money m3 = new Money(5000, "eur");
		Money m4 = new Money(1000, "eur");
		Money m5 = new Money(500, "eur");

		Duration d1 = new Duration(15);
		Duration d2 = new Duration(10);
		Duration d3 = new Duration(8);
		Duration d4 = new Duration(5);
		Duration d5 = new Duration(3);

		InterestRate ir1 = new InterestRate(10);
		InterestRate ir2 = new InterestRate(8);
		InterestRate ir3 = new InterestRate(6.7);
		InterestRate ir4 = new InterestRate(5);
		InterestRate ir5 = new InterestRate(3.1);

		Offer o1 = new Offer((long) 2020, "das ist ein kommentar", ir1);
		o1.setInterestRate(ir1);
		Offer o2 = new Offer((long) 2030, "das ist kein kommentar", ir2);
		o2.setInterestRate(ir2);
		Offer o3 = new Offer((long) 2040, "mein glas ist leer", ir3);
		o3.setInterestRate(ir3);
		Offer o4 = new Offer((long) 2050, "ich fülle mein glas wieder auf", ir4);
		o4.setInterestRate(ir4);
		Offer o5 = new Offer((long) 2060, "bin wieder da", ir5);
		o5.setInterestRate(ir5);

		InternalCustomer c1 = new InternalCustomer(101, "Asdf", "Fghj", "Rt",
				new BigDecimal(10000), a1, dp1);
		InternalCustomer c2 = new InternalCustomer(102, "Qwer", "Ghjk", "Tzu",
				new BigDecimal(20000), a2, dp2);
		InternalCustomer c3 = new InternalCustomer(103, "Yxcv", "Hjkl", "Zuio",
				new BigDecimal(40000), a3, dp3);
		InternalCustomer c4 = new InternalCustomer(104, "Sdfg", "Jklö",
				"Uiopü", new BigDecimal(50000), a4, dp4);
		InternalCustomer c5 = new InternalCustomer(105, "Dfgh", "Klöä",
				"Iopüas", new BigDecimal(60000), a5, dp5);

		Warrantor w1 = new Warrantor(201, "Qw", "Op", "Fg", new BigDecimal(
				10000), a1, dp1);
		Warrantor w2 = new Warrantor(202, "Er", "Pü", "Gh", new BigDecimal(
				10000), a1, dp1);
		Warrantor w3 = new Warrantor(203, "Rt", "As", "Hj", new BigDecimal(
				10000), a1, dp1);
		Warrantor w4 = new Warrantor(204, "Zu", "Sd", "Jk", new BigDecimal(
				10000), a1, dp1);
		Warrantor w5 = new Warrantor(205, "Io", "Df", "Kl", new BigDecimal(
				10000), a1, dp1);

		CreditRequest cr1 = new CreditRequest(901, "haus", null, m1, d1, c1);
		cr1.setMoney(m1);
		cr1.setDuration(d1);
		cr1.setCustomer(c1);
		cr1.addWarrentor(w1);
		cr1.addWarrentor(w2);
		CreditRequest cr2 = new CreditRequest(902, "auto", null, m2, d2, c2);
		cr2.setMoney(m2);
		cr2.setDuration(d2);
		cr2.setCustomer(c2);
		cr2.addWarrentor(w3);
		cr2.addWarrentor(w4);
		CreditRequest cr3 = new CreditRequest(903, "pool", null, m3, d3, c3);
		cr3.setMoney(m3);
		cr3.setDuration(d3);
		cr3.setCustomer(c3);
		cr3.addWarrentor(w1);
		cr3.addWarrentor(w5);
		CreditRequest cr4 = new CreditRequest(904, "möbel", null, m4, d4, c4);
		cr4.setMoney(m4);
		cr4.setDuration(d4);
		cr4.setCustomer(c4);
		cr4.addWarrentor(w2);
		cr4.addWarrentor(w4);
		CreditRequest cr5 = new CreditRequest(905, "casino", null, m5, d5, c5);
		cr5.setMoney(m5);
		cr5.setDuration(d5);
		cr5.setCustomer(c5);
		cr5.addWarrentor(w1);
		cr5.addWarrentor(w3);
		CreditRequest cr6 = new CreditRequest(901, "casino", null, m5, d5, c5);
		cr6.setMoney(m5);
		cr6.setDuration(d5);
		cr6.setCustomer(c1);
		cr6.addWarrentor(w1);
		cr6.addWarrentor(w2);

		c1.addCreditRequest(cr1.getRequestId());
		c1.addCreditRequest(cr6.getRequestId());
		c2.addCreditRequest(cr2.getRequestId());
		c3.addCreditRequest(cr3.getRequestId());
		c4.addCreditRequest(cr4.getRequestId());
		c5.addCreditRequest(cr5.getRequestId());

		w1.addCreditRequestAsWarentor(cr1.getRequestId());
		w1.addCreditRequestAsWarentor(cr3.getRequestId());
		w1.addCreditRequestAsWarentor(cr5.getRequestId());
		w1.addCreditRequestAsWarentor(cr6.getRequestId());
		w2.addCreditRequestAsWarentor(cr1.getRequestId());
		w2.addCreditRequestAsWarentor(cr4.getRequestId());
		w2.addCreditRequestAsWarentor(cr6.getRequestId());
		w3.addCreditRequestAsWarentor(cr2.getRequestId());
		w3.addCreditRequestAsWarentor(cr5.getRequestId());
		w4.addCreditRequestAsWarentor(cr2.getRequestId());
		w4.addCreditRequestAsWarentor(cr4.getRequestId());
		w5.addCreditRequestAsWarentor(cr3.getRequestId());


		requests.add(cr1);
		requests.add(cr2);
		requests.add(cr3);
		requests.add(cr4);
		requests.add(cr5);
		/*
		 * long requestId, String reason, Offer offer, Money money, Duration
		 * duration, InternalCustomer customer
		 * 
		 * Offer o = new Offer(); o.setComments("offer comment");
		 * 
		 * InternalCustomer c1 = new InternalCustomer(); c1.setAddress(a1);
		 * c1.setCustomerId((long)123); c1.setFirstName("Vorname");
		 * c1.setMiddleName("Mittlename"); c1.setLastName("Nachname");
		 * c1.setOpenBalance(new BigDecimal(3.14)); DisbursementPreference
		 * dp=new Cheque("bla blub"); c1.setDistbursement(dp); c1.setRating(new
		 * Rating("AAA"));
		 * 
		 * CreditRequest cr = new CreditRequest((long)10101, "irgendwas", new
		 * Offer((long)2020, "das ist ein kommentar", new InterestRate()), new
		 * Money(), new Duration(), c1); Warrantor w1 = new Warrantor();
		 * w1.setFirstName("Asdf"); w1.setLastName("Qwert");
		 * cr.addWarrentor(w1); Warrantor w2 = new Warrantor();
		 * w2.setFirstName("Wertz"); w2.setLastName("Sdfg");
		 * cr.addWarrentor(w2); cr.setCustomer(c1); cr.setOffer(o);
		 * 
		 * 
		 * return cr;
		 */
	}

}